/*******************************************************************************
 * 文件名: XWorkbook.java
 * 描    述: Excel对象
 * 创建人: Dean Huang(hudi-112@163.com)
 * 日　期: 2018-01-11
 * 描　述: 文件描述
 * 版　本: 1.0
 *******************************************************************************/

package com.z1.core.data.export.excel;

import java.lang.reflect.Method;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class XWorkbook {

	public final static int EXCEL2003 = 2003;
	public final static int EXCEL2007 = 2007;
	
	private static CellStyle getHeaderStyle(Workbook workbook) {
		CellStyle headerStyle = workbook.createCellStyle();
		headerStyle.setFillForegroundColor((short)17);
		headerStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
		Font headFont = workbook.createFont();
		headFont.setColor(Font.COLOR_NORMAL);
		headFont.setFontHeightInPoints((short)10);
		headFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
		headerStyle.setFont(headFont);
		return headerStyle;
	}
	
	private static Workbook createWorkbook(int version, String password) {
		if (EXCEL2003 == version) {
			HSSFWorkbook workbook = new HSSFWorkbook();
			if (null != password) {
				workbook.writeProtectWorkbook(password, "");
			}
			return workbook;
		}
		else if (EXCEL2007 == version) {
			XSSFWorkbook workbook = new XSSFWorkbook();
			if (null != password) {
				workbook.setWorkbookPassword(password, null);
			}
			return workbook;
		}
		return null;
	}
	
	public static Workbook getWorkbook(int version, List<Object[]> values) {
		return getWorkbook(version, values);
	}
	public static Workbook getWorkbook(int version, List<Object[]> values, String password) {
		Workbook workbook = createWorkbook(version, password);
		if (null != workbook) {
			CellStyle headerStyle = getHeaderStyle(workbook);
			createCells(workbook, headerStyle, values);
		}
		return workbook;
	}
	
	public static Workbook getWorkbook(int version, String[] headers, List<Object[]> values) {
		return getWorkbook(version, headers, values);
	}
	public static Workbook getWorkbook(int version, String[] headers, List<Object[]> values, String password) {
		Workbook workbook = createWorkbook(version, password);
		if (null != workbook) {
			CellStyle headerStyle = getHeaderStyle(workbook);
			values.add(0, headers);
			createCells(workbook, headerStyle, values);
		}
		return workbook;
	}
	
	public static <T> Workbook getWorkbook(int version, String[][] header, List<T> values) {
		return getWorkbook(version, header, values, null);
	}
	public static <T> Workbook getWorkbook(int version, String[][] header, List<T> values, String password) {
		Workbook workbook = createWorkbook(version, password);
		if (null != workbook) {
			CellStyle headerStyle = getHeaderStyle(workbook);
			createCells(workbook, headerStyle, header, values);
		}
		return workbook;
	}
	
	private static void createCells(Workbook workbook, CellStyle headerStyle, List<Object[]> values) {
		Sheet sheet = workbook.createSheet("data");
		for (int i = 0; i < values.size(); i++) {
			Row row = sheet.createRow(i);
			Object[] vs = values.get(i);
			if (0 == i) {
				for (int j = 0; j < vs.length; j++) {
					Cell cell = row.createCell(j);
					cell.setCellValue(vs[j].toString());
					cell.setCellStyle(headerStyle);
				}
			}
			else {
				for (int j = 0; j < vs.length; j++) {
					Cell cell = row.createCell(j);
					cell.setCellValue(vs[j].toString());
				}
			}
		}
	}
	
	private static <T> void createCells(Workbook workbook, CellStyle headerStyle, String[][] header, List<T> values) {
		Sheet sheet = workbook.createSheet("data");
		Row row = sheet.createRow(0);
		for (int i = 0; i < header.length; i++) {
			Cell cell = row.createCell(i);
			cell.setCellValue(header[i][0]);
			cell.setCellStyle(headerStyle);
			header[i][1] = header[i][1].substring(0, 1).toUpperCase() + header[i][1].substring(1);
		}
		for (int i = 0; i < values.size(); i++) {
			T t = values.get(i);
			row = sheet.createRow(i + 1);
			for (int j = 0; j < header.length; j++) {
				Cell cell = row.createCell(j);
				Object v = null;
				try {
					Method method = t.getClass().getDeclaredMethod("get" + header[j][1], new Class<?>[]{});
					v = method.invoke(t, new Object[]{});
				} catch (Exception e) {
					e.printStackTrace();
				}
				if (null == v) {
					cell.setCellValue("");
				}
				else {
					cell.setCellValue(v.toString());
				}
			}
		}
	}
}
